package chjob

import (
	"fmt"
	"math"
	"sort"
	"time"
)

// 2、利用第1题，构造3个以上图形，至少圆形、三角形、矩形各有一个，对上题的图形按照面积降序排列
type Area interface {
	Area() float32
}

// 图形面积
type Shape struct {
	area float32
}

// 圆类
type circle struct {
	Shape
	radius float32
}

// 三角
type triangle struct {
	Shape
	base float32
	high float32
}

// 长方形
type oblong struct {
	Shape
	high float32
	wide float32
}

// 圆方法
func (c *circle) Area() float32 {
	p := math.Pi
	c.area = float32(p) * c.radius * c.radius
	return c.area
}

// 三角形方法
func (t *triangle) Area() float32 {
	t.area = 0.5 * t.base * t.high
	return t.area
}

// 长方形方法
func (o *oblong) Area() float32 {
	o.area = o.high * o.wide
	return o.area
}

// 构造函数
// 圆形 构造函数
func NewCircle(radius float32) *circle {
	return &circle{radius: radius}
}

// 三角形构造函数
func NewTriangle(base, high float32) *triangle {
	return &triangle{base: base, high: high}
}

// 长方形构造函数
func NewOblong(high, wide float32) *oblong {
	return &oblong{high: high, wide: wide}
}

func Ch04_02() {
	// 圆形面积
	c1 := NewCircle(4.4)
	fmt.Printf("圆形c1的面积是%.2f\n", c1.Area())

	// 三角形面积
	t1 := NewTriangle(0.5, 4)
	fmt.Printf("三角形t1的面积是%.2f\n", t1.Area())

	// 长方形面积
	o1 := NewOblong(2, 4)
	fmt.Printf("长方形o1的面积是%.2f\n", o1.Area())

	// 排序  实现了Area方法，就是Area接口类型
	shapes := []Area{c1, t1, o1}
	sort.Slice(shapes, func(i, j int) bool {
		return shapes[i].Area() > shapes[j].Area()
	})
	// 降序输出
	for _, v := range shapes {
		fmt.Printf("%.2[1]f\n", v.Area())
	}
}

// 3、分析斐波那契数列递推公式递归版本的问题，试着为该函数提供一个Cache，使其计算效率提升
// 保存已经计算过的斐波那契数
var map1 = make(map[int]int, 0)

func Ch04_03(n int) int {
	switch {
	case n < 0:
		panic("n is negative")
	case n == 0:
		return 0
	case n < 3:
		return 1
	}
	if v, ok := map1[n]; ok {
		return v
	}

	map1[n] = Ch04_03(n-1) + Ch04_03(n-2)
	return map1[n]
}

func Ch04_04() {
	// 4、8年前的今天上午9点30分
	now1 := time.Now().AddDate(-8, 0, 0)
	date1 := now1.Format("2006-01-02")
	time1 := "09:30:00"
	zone1 := now1.Format("-0700")
	t1 := fmt.Sprintf("%s %s %s", date1, time1, zone1)
	t, err := time.Parse("2006-01-02 15:04:05 -0700", t1)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%v\n", t)

	// 要求：
	// 1. 毫秒时间戳是多少？
	fmt.Println(t.UnixMilli())
	// 2. 格式化输出时间为 2005/09/10 21:35:40 +0800 的形式
	fmt.Println(t.Format("2006/01/02 15:04:05 -0700"))
	// 3. 请问那天是周几？到那天，本年已经过了多少周？
	fmt.Printf("那天是周%v\n", int(t.Weekday()))
	y, w := t.ISOWeek()
	fmt.Printf("%v年的第%v周\n", y, w)
	// 4. 距离今天已经过了多少天了？
	// k := time.Since(t).Hours()
	n1 := time.Now()
	d := n1.Sub(t).Hours()
	fmt.Printf("距离今天已经过了%v", int(d)/24)
}
